home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2006 November
/
PCWorld_2006-11_cd.bin
/
domacnost a kancelar
/
findgraph
/
fgraph.exe
/
{app}
/
ApprSource
/
ExpPow.cpp
next >
Wrap
C/C++ Source or Header
|
2004-07-02
|
9KB
|
376 lines
/******************************************************************************
* Plug-In DLL Example and Template
* for use with C/C++
*
* Compile DLL with any name.
* Place it in the program FindGraph subfolder "Appr".
* Next functions must be exported:
* MaxOfFactors
* Prepare
* CalcInPoint
* FunctionTitle
* FunctionName
* FunctionString
* ParamInfo
*
* To test DLL, restart FundGraph,
* start The Wizard of approximation,
* on step 2 select 'User defined function'.
* If all right, on step 3 your function will appear in list.
*
******************************************************************************/
#include <windows.h>
#include <tchar.h>
#include <math.h>
#include "exppow.h"
#include <stdio.h>
//
#pragma comment(linker,"/MERGE:.rdata=.text")
#pragma comment(linker,"/FILEALIGN:512 /SECTION:.text,EWRX /IGNORE:4078")
//////////////////////////////////////////////////////////////////////////////////
HINSTANCE g_hInstance=NULL;
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInstance = (HINSTANCE )hModule;
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#define N_FACTORS 10
#define aa(i,j) pfs[i*nn+j]
// 2 linear equations
// Input
// pfs = matrix [2,3]
// Output
// pfu - vector [2]
//
void CalcEquGauss2(double *pfs, double *pfu)
{
int n = 1,
nn = n+2;
double d = aa(0,0) * aa(1,1) - aa(0,1)*aa(1,0);
if (d == 0.)
{
pfu[1] = 0.;
pfu[0] = (aa(0,0) != 0.) ? aa(0,2) / aa(0,0) : 0.;
}
else
{
pfu[0] = (aa(1,1)*aa(0,2) - aa(0,1)*aa(1,2)) / d;
pfu[1] = (aa(0,0)*aa(1,2) - aa(1,0)*aa(0,2)) / d;
}
}
// Error of calculus
//
double CalcError(double *pfU, double *pfV, int nPoints,
double *pfFactors, int nFactors)
{
if (nPoints <= 0)
return 0.;
double fError = 0.;
for (int id=0; id < nPoints; id++ )
{
double u = pfU[id],
v = pfV[id],
v1= CalcInPoint(u, pfFactors, nFactors);
fError += (v1-v)*(v1-v);
}
fError = sqrt(fError/nPoints);
return fError;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Return the number of factors (see function 'Prepare')
// use to memory allocate for pfFactors
//
//extern "C" bool __declspec( dllexport ) __stdcall TransFromDisk(char *Base, char *Disk);
int __declspec(dllexport) __stdcall MaxOfFactors()
{
return N_FACTORS;
}
//
// Prepare approximation function V(U) = Function(U)
// V(U) = V0 + exp(a*(U-U0))*Pow((U-U0), b)
// Input:
// Array of points (U,V)
// fMinU, fMaxU - limits of U
// fMinV, fMaxV - limits of V
// pfU, pfV - array of nPoints points (U,V)
// pfW - weight of point
// nPoints - number of points in array
// Parameters:
// pfParams - array of parameters
// U0 = pfParams[0]
// V0 = pfParams[1]
// nParams - number of parameters in array
//
// Output:
// Array of factors is calculated.
// This factors will be used in function CalcInPoint(U, pfFactors)
// pfFactors - array of factors, defined by user
// Notes: pfFactors[*pnFactors-1] = Error of calculus
// nFactors:
// Input - maximum possible number of factors in array
//
// return: number of factors if success, else error code
//
int __declspec(dllexport) __stdcall Prepare (double fMinU, double fMaxU, double fMinV, double fMaxV,
double *pfU, double *pfV, double *pfW, int nPoints,
double *pfParams , int nParams ,
double *pfFactors, int nFactors)
{
int nResult = 0;
if (nPoints < 2) // not enough points
return -1;
if (nFactors < N_FACTORS) // not enough memory for result
return -2;
int
nAppr = 1,
nn = nAppr + 2,
ns =(nAppr+1)*(nn+1);
double fU0 = fMinU,
fV0 = fMinV;
if (nParams > 0) fU0 = pfParams[0];
if (nParams > 1) fV0 = pfParams[1];
double
*pfs,
*pfu;
// use: aa(i,j) == pfs[i*nn+j]
pfu = new double[nAppr+1];// calced coeff
pfs = new double[ns];
memset(pfs, 0, ns*sizeof(double));
int nSum = 0; // point with U>0, V>0
for (int id=0; id < nPoints; id++ )
{
double u = pfU[id] - fU0,
v = pfV[id] - fV0;
if (u > 0. && v > 0.)
{
double lu = log(u),
lv = log(v);
aa(0,0) += u* u;
aa(0,1) += u*lu;
aa(0,2) += u*lv;
aa(1,0) += lu* u;
aa(1,1) += lu*lu;
aa(1,2) += lu*lv;
nSum++;
}
}
if (nSum >= 2)
{
CalcEquGauss2(pfs, pfu);
nResult = N_FACTORS;
pfFactors[0] = nSum;
pfFactors[1] = fMinU; pfFactors[2] = fMaxU; // Unused now - reserved
pfFactors[3] = fMinV; pfFactors[4] = fMaxV; // Unused now - reserved
pfFactors[4] = 0; // Unused now - reserved
pfFactors[5] = fU0;
pfFactors[6] = fV0;
pfFactors[7] = pfu[0]; // a
pfFactors[8] = pfu[1]; // b
pfFactors[N_FACTORS-1] = CalcError(pfU, pfV, nPoints, pfFactors, nFactors);
}
delete [] pfu;
delete [] pfs;
return nResult;
}
// Calculate value V = Function(fU)
// Input:
// fU
// pfFactors - array of factors, prepared in finction Prepare()
// pnFactors: - number of factors in array
//
// return: value calculated
//
double __declspec(dllexport) __stdcall CalcInPoint(double fU,
double *pfFactors, int nFactors)
{
double fV = 0.;
if (nFactors < N_FACTORS)
return 0.;
double
U0 = pfFactors[5],
V0 = pfFactors[6],
a = pfFactors[7],
b = pfFactors[8],
U = fU - U0;
if (U <= 0.)
return 0.;
fV = V0 + exp(a*U)*pow(U, b);
return fV;
}
// Fill information string with name of approximation method
// It is used in FindGraph <Master of approximations page 2><list of user defined functions>
// for example - "User's ExpPow"
// Input:
// pstr - buffer TCHAR
// nMaxLength - maximum buffer length
//
// Output:
// pstr - name of approximation method
//
// return: string length if success, else -1
//
int __declspec(dllexport) __stdcall FunctionTitle(LPTSTR pstr, int nMaxLength)
{
if (pstr==0)
return -1;
lstrcpyn(pstr, TEXT(" Y = Exp(a*X)*Pow(x,b) (see sample in directory \'ApprSource\')"), nMaxLength);
return lstrlen(pstr);
}
// Fill information string with name of approximation function
// for example - "V(U) = V0 + Exp(a*(U-U0))*Pow((U-U0), b)"
// It is used in FindGraph <Master of approximations page 3><Function description>
// Input:
// pstr - buffer TCHAR
// nMaxLength - maximum buffer length
//
// Output:
// pstr - name of approximation function
//
// return: string length if success, else -1
//
int __declspec(dllexport) __stdcall FunctionName(LPTSTR pstr, int nMaxLength)
{
if (pstr==0)
return -1;
lstrcpyn(pstr, TEXT("f(U) = V0 + Exp(a*(U-U0))*Pow((U-U0), b)"), nMaxLength);
return lstrlen(pstr);
}
// Fill information string with formula of calculated function f(U) = Formula()
// for example - "V(U) = 1. + Exp(2*(U-3.))*Pow((U-3.), 4)"
// It is used in FindGraph <Master of approximations pages 4 and 5>
// Input:
// pstr - buffer TCHAR
// nMaxLength - maximum buffer length
// pfFactors - array of factors, prepared in finction Prepare()
// pnFactors: - number of factors in array
//
// Output:
// pstr - string of calculated function f(U)
//
// return: string length if success, else -1
//
int __declspec(dllexport) __stdcall FunctionString(double *pfFactors, int nFactors,
LPTSTR pstr, int nMaxLength)
{
if (pstr==0)
return -1;
if (nFactors < N_FACTORS)
return -2;
TCHAR sz[256];
double
U0 = pfFactors[5],
V0 = pfFactors[6],
a = pfFactors[7],
b = pfFactors[8];
sprintf(sz, TEXT("f(U) = %4.4g + Exp(%4.2f*(U-%4.4g))*Pow((U-%4.4g), %4.2f)"), V0, a, U0, U0, b);
lstrcpyn(pstr, sz, nMaxLength);
return lstrlen(pstr);
}
// Fill information string with name of parameter and it's default value
// It is used in FindGraph <Master of approximations page 3>
// Input:
// nParam - number of edit box in page 3
// 1, 2, 3, 4
// see list of pfParams in function 'Prepare'
// pstr - buffer TCHAR
// nMaxLength - maximum buffer length
//
// Output:
// pstr - name of parameter[nParam]
// pfDefault - default value of parameter[nParam]
//
// return: string length if success, else -1
//
int __declspec(dllexport) __stdcall ParamInfo(int nParam, LPTSTR pstr, int nMaxLength, double *pfDefault)
{
if (pstr==0)
return -1;
switch (nParam)
{
case 1:
lstrcpyn(pstr, TEXT("U0"), nMaxLength);
if (pfDefault != NULL)
*pfDefault = 0.;
break;
case 2:
lstrcpyn(pstr, TEXT("V0"), nMaxLength);
if (pfDefault != NULL)
*pfDefault = 0.;
break;
case 3:
case 4:
lstrcpyn(pstr, TEXT("unused"), nMaxLength);
if (pfDefault != NULL)
*pfDefault = 0.;
break;
default: return -1;
}
//*pfDefault = 10+nParam;
return lstrlen(pstr);
}